// --- Copyright (c) 2006-2008 Stefan Kyntchev ---
// This software is written and copyrighted by Stefan Kyntchev 
// and BeyondPod Team members. All rights are reserved.
// Author contact: support@beyondpod.mobi
// ------------------------------------------------------------------------
// This file is part of BeyondPod RSS Feed Reader and Podcast manager
// (www.codeplex.com/BeyondPod) 
// BeyondPod is free software: you can redistribute it and/or modify 
// it under the terms of the GNU General Public License as published by 
// the Free Software Foundation, either version 3 of the License, or 
// (at your option) any later version. 
//  
// BeyondPod is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
// GNU General Public License for more details. 
//  
// You should have received a copy of the GNU General Public License
// along with BeyondPod. If not, see <http://www.gnu.org/licenses/>
// ------------------------------------------------------------------------
// COPYRIGHT NOTICE: This copyright notice may NOT be removed, obscured or modified 
// without written consent from the author.
// --- End copyright notice --- 


using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using svs.Mobile.BeyondMedia.FeedCore;
using svs.Mobile.BeyondMedia.FeedCore.Helpers;
using svs.Mobile.BeyondMedia.FeedCore.RSS;
using svs.Mobile.BeyondMedia.FeedCore.SysIntegration;
using svs.Mobile.BeyondMedia.Objects;
using OpenFileDialog=OpenNETCF.Windows.Forms.OpenFileDialog;

namespace svs.Mobile.BeyondMedia
{
	public partial class Opml : Form
	{
		private List<MenuItem> m_CategoriesMenu;
		private Feed m_LastImportedFeed = null;
		private Feed m_OpmlFeed;

		public Opml()
		{
			InitializeComponent();

			OpmlFeeds.BackClick += delegate
			                       	{
			                       		OnMenuBack(null, null);
			                       	};
		}

		public Feed OpmlFeed
		{
			get { return m_OpmlFeed; }
			set { m_OpmlFeed = value; }
		}

		private string SelectedFile
		{
			get { return OpmlFile.Text.Trim(); }
		}

		private ImportSource Source
		{
			get { return (ImportSource) ImportLocation.SelectedIndex; }
		}

		private void SetCurrentView(ViewType type)
		{
			if (type == ViewType.SelectFeed)
			{
				SelectOpmlPnl.Visible = true;
				OpmlFeeds.Visible = false;
				menuNext.Click -= OnMenuImport;
				menuNext.Click += OnMenuNext;
				Text = "Import Feeds";
				menuNext.Text = "Next";
				menuNext.Enabled = true;
				menuNext.MenuItems.Clear();
				BrowseLink.Focus();
			}
			else
			{
				SelectOpmlPnl.Visible = false;
				OpmlFeeds.Visible = true;
				menuNext.Click -= OnMenuNext;
				menuNext.Click += OnMenuImport;
				OpmlFeeds.Focus();
			}
		}

		private void OnBrowseClick(object sender, EventArgs e)
		{
			OpenFileDialog dlg = new OpenFileDialog();

			string dir = Path.GetDirectoryName(SelectedFile);
			if (Directory.Exists(dir))
				dlg.InitialDirectory = dir;

			if (dlg.ShowDialog() == DialogResult.OK)
			{
				OpmlFile.Text = dlg.FileName;
				OnMenuNext(null, null);
			}
		}

		private void OnMenuImport(object sender, EventArgs e)
		{
			if (OpmlFeeds.SelectedFeed != null)
			{
				bool import = false;
				Feed f = FeedRepository.GetFeedByUrl(OpmlFeeds.SelectedFeed.FeedUrl);

				if (f == null)
				{
					f = new Feed(Guid.NewGuid(), FeedRepository.RootFeed);
					import = true;
				}

				f.Name = OpmlFeeds.SelectedFeed.Name;
				f.FeedUrl = OpmlFeeds.SelectedFeed.FeedUrl;

				//Assign a category to the imported feed
				FeedCategory importCategory = Configuration.ActiveFeedCategory;
				if (f.Categories.IsOfCategory(CategoryManager.Unassigned))
				{
					string categoryName = null;
					MenuItem m = sender as MenuItem;

					if (m != null)
					{
						categoryName = m.Text;
					}
					else if (OpmlFeeds.SelectedFeed.ParentFeed != null)
						//if pArent't feeds name (folder name) ia a valid categoty name  - use it
					{
						categoryName = OpmlFeeds.SelectedFeed.ParentFeed.Name;
					}

					if (!string.IsNullOrEmpty(categoryName))
					{
						FeedCategory c = CategoryManager.GetCategoryByValue(categoryName);
						if (c != CategoryManager.CategoryNull)
							importCategory = c;
					}

					f.Categories.Primary = importCategory;
				}

				m_LastImportedFeed = f;

				if (import)
					FeedRepository.RootFeed.Feeds.Add(f);

				OpmlFeeds.NotifyFeedStatusChanged(OpmlFeeds.SelectedFeed);
				OnSelectedFeedChanged(null, null);
			}
		}

		private void OnMenuNext(object sender, EventArgs e)
		{
			try
			{
				if (Source == ImportSource.OPML)
					LoadOpmlFile();
				else
					LoadGoogleReaderSubscriptions();

				SetCurrentView(ViewType.FeedList);
			}
			catch (Exception ex)
			{
				InfoLabel.Text = ex.Message;
			}
		}

		private void LoadGoogleReaderSubscriptions()
		{
			try
			{
				Cursor.Current = Cursors.WaitCursor;

				InfoLabel.Text = "Connecting...";
				Application.DoEvents();
				GoogleReader.LogIn(GUserName.Text, GPassword.Text);

				if (!GoogleReader.IsLoggedIn)
				{
					throw new ApplicationException("Login Failed!");
				}

				InfoLabel.Text = "Loading Feeds...";
				Application.DoEvents();
				Feed imported = GoogleReader.GetFeedList();

				InfoLabel.Text = string.Empty;
				SetCurrentFeed(imported, null);
			}
			catch (Exception ex)
			{
				CoreHelper.WriteLogEntry("Unbale to read feed list from Goolge. Reason: " + ex);
				throw;
			}
			finally
			{
				Cursor.Current = Cursors.Default;
			}
		}

		private void LoadOpmlFile()
		{
			try
			{
				Cursor.Current = Cursors.WaitCursor;

				if (!File.Exists(SelectedFile))
					throw new ArgumentException("Selected file does not exist!");

				Feed imported = OpmlManager.LoadOpml(SelectedFile);
				if (imported != null)
				{
					if (OpmlFeed != null)
					{
						OpmlFeed.UpdateNameIfDefault(imported.Name);
					}

					SetCurrentFeed(imported, null);
				}
				else
				{
					throw new ApplicationException("Unable to load the selected file!");
				}
			}
			finally
			{
				Cursor.Current = Cursors.Default;
			}
		}

		private void SetCurrentFeed(Feed feed, Feed selected)
		{
			OpmlFeeds.SetRootFeed(feed, selected);
			Text = feed.Name;
			OnSelectedFeedChanged(null, null);
		}

		private void OnMenuBack(object sender, EventArgs e)
		{
			if (SelectOpmlPnl.Visible)
			{
				if (File.Exists(SelectedFile))
					Configuration.LastImportedOPMLPath = OpmlFile.Text.Trim();

				CloseDialog();
			}
			else
			{
				Feed current = OpmlFeeds.Feed; //back the parent feed
				if (current.ParentFeed != null)
				{
					SetCurrentFeed(current.ParentFeed, current);
				}
				else
				{
					if (OpmlFeed == null)
						SetCurrentView(ViewType.SelectFeed); //switch to file selector if we did not start with known file
					else
						CloseDialog();
				}
			}
		}

		private void CloseDialog()
		{
			Close();
		}

		private void OnFeedSelected(Feed aFeed, FeedViewType type)
		{
			if (aFeed.Equals(FeedRepository.GoUpPlaceholder) && OpmlFeeds.Feed.ParentFeed != null)
			{
				SetCurrentFeed(OpmlFeeds.Feed.ParentFeed, OpmlFeeds.Feed);
				return;
			}

			if (OpmlFeeds.SelectedFeed != null && OpmlFeeds.SelectedFeed.Feeds.Count > 0)
			{
				SetCurrentFeed(OpmlFeeds.SelectedFeed, null);
			}
		}

		private void OnSelectedFeedChanged(object sender, EventArgs e)
		{
			Feed f = OpmlFeeds.SelectedFeed;

			if (f == null)
			{
				menuNext.Enabled = false;
				menuNext.Text = String.Empty;
				return;
			}

			if (f.HasUrl)
			{
				if (FeedRepository.GetFeedByUrl(f.FeedUrl) == null)
				{
					menuNext.Text = "Import To...";
					BuildImportCategories();
				}
				else
				{
					menuNext.Text = "Replace";
					menuNext.MenuItems.Clear();
				}
			}
			else
			{
				menuNext.Text = String.Empty;
			}

			menuNext.Enabled = f.HasUrl;
		}

		private void BuildImportCategories()
		{
			if (m_CategoriesMenu == null)
			{
				CategoryList categories = CategoryManager.GetCategoriesForAssignment();
				m_CategoriesMenu = new List<MenuItem>(categories.Count);

				foreach (FeedCategory category in categories)
				{
					MenuItem menu = new MenuItem();
					menu.Text = category.Name;
					menu.Click += OnMenuImport;
					m_CategoriesMenu.Add(menu);
				}
			}

			if (menuNext.MenuItems.Count == 0)
			{
				foreach (MenuItem item in m_CategoriesMenu)
				{
					menuNext.MenuItems.Add(item);
				}
			}
		}

		private void OnLoad(object sender, EventArgs e)
		{
			ImportLocation.SelectedIndex = 0;
			OnSourceChanged(null, null);

			GUserName.Text = Configuration.GoogleReaderUserName;
			GPassword.Text = Configuration.GoogleReaderPassword;

			if (!string.IsNullOrEmpty(Configuration.LastImportedOPMLPath))
				OpmlFile.Text = Configuration.LastImportedOPMLPath;

			//If we know what file to import
			if (OpmlFeed != null && OpmlFeed.HasUrl)
			{
				string file = RssFeedCache.GetFeedDownloadPath(CoreHelper.SafeCreateUri(OpmlFeed.FeedUrl));
				if (Source == ImportSource.OPML && !string.IsNullOrEmpty(file))
				{
					OpmlFile.Text = file;
					OnMenuNext(null, null);
				}
			}
		}

		private void OnSourceChanged(object sender, EventArgs e)
		{
			if (Source == ImportSource.OPML)
			{
				pnlOPML.Visible = true;
				pnlGoogle.Visible = false;
			}
			else
			{
				pnlOPML.Visible = false;
				pnlGoogle.Visible = true;
			}
		}

		#region Nested type: ImportSource

		private enum ImportSource
		{
			OPML,
			GoogleReader
		}

		#endregion

		#region Nested type: ViewType

		private enum ViewType
		{
			SelectFeed,
			FeedList
		}

		#endregion

		private void OnClosing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			Configuration.GoogleReaderUserName = GUserName.Text;
			Configuration.GoogleReaderPassword = GPassword.Text;

			if (m_LastImportedFeed != null)
			{
				FeedRepository.SortFeeds(FeedRepository.RootFeed);
				ViewManager.Feeds.Reload();
				ViewManager.Feeds.SelectedFeed = m_LastImportedFeed;
				FeedRepository.AutoSaveRepository();
			}
		}
	}
}